package com.wxf.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 发布订阅模式
 * 要素：生产者、交换机、队列、消费者
 */
public class Producer {
    // 交换机是fanout类型
    public static String DIRECT_EXCHANGE = "direct_exchange";
    // 假设有两个队列
    public static String DIRECT_QUEUE_INSERT = "direct_queue_insert";
    public static String DIRECT_QUEUE_UPDATE = "direct_queue_update";

    public static void main(String[] args) {
        // 1-创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.127.131");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("123456");
        connectionFactory.setVirtualHost("/");
        // 2-创建连接
        Connection conn = null;
        Channel channel = null;
        try {
            conn = connectionFactory.newConnection("生产者");

            // 3-创建通道
            channel = conn.createChannel();
            // 4-声明交换机
            // 参数1：交换机名称；
            // 参数2：交换机类型；
            channel.exchangeDeclare(DIRECT_EXCHANGE,"direct");
            // 5-声明队列
            // 参数说明：
            // 参数1：队列名称；
            // 参数2：是否持久化；
            // 参数3：排他性，是否独占队列，即只有一个消费者监听队列
            // 参数4：是否自动删除，即最后一个消费者消费完信息后是否自动删除队列
            // 参数5：携带附属参数
            channel.queueDeclare(DIRECT_QUEUE_INSERT,true,false,false,null);
            channel.queueDeclare(DIRECT_QUEUE_UPDATE,true,false,false,null);
            // 6-绑定交换机和队列
            // 参数1：队列名称；
            // 参数2：交换机名称；
            // 参数3：路由
            channel.queueBind(DIRECT_QUEUE_INSERT,DIRECT_EXCHANGE,"insert");
            channel.queueBind(DIRECT_QUEUE_UPDATE,DIRECT_EXCHANGE,"update");

            // 7-发送消息给队列
            String insertMsg = "insert insert insert";
            String updateMsg = "update update update";
                // 参数说明：
                // 参数1：交换机
                // 参数2：队列、路由key
                // 参数3：消息的状态控制
                // 参数4：消息主体
                // 因为这里是交换机发送信息给队列，队列名称就不用写了，channel把信息发给交换机即可
                channel.basicPublish(DIRECT_EXCHANGE,"insert",null,insertMsg.getBytes());
                channel.basicPublish(DIRECT_EXCHANGE,"update",null,updateMsg.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }finally {
            //7-关闭通道
            if(channel!=null&&channel.isOpen()){
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            // 8-关闭连接
            if(conn!=null&&conn.isOpen()){
                try {
                    conn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
